package com.open.capacity.finance.task.gdszcz;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.open.capacity.finance.config.Globals;
import com.open.capacity.finance.entity.SpringScheduledCron;
import com.open.capacity.finance.service.SpringScheduledCronService;
import com.open.capacity.finance.task.ScheduledOfTask;
import com.open.capacity.finance.util.GDSZCZUtils;
import com.open.capacity.reptile.constant.GDSZCZConstant;
import com.open.capacity.reptile.dto.gdszcz.request.CommonRequest;
import com.open.capacity.reptile.dto.gdszcz.response.CommonResponse;
import com.open.capacity.reptile.entity.*;
import com.open.capacity.reptile.service.*;
import com.open.capacity.reptile.util.HttpUtils;
import com.open.capacity.user.model.SysCompany;
import com.open.capacity.user.service.SysConfigService;
import com.open.capacity.utils.DateUtil;
import com.open.capacity.utils.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.Header;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.task.TaskExecutor;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.text.MessageFormat;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;

/**
 * 杂项数据同步
 */
@Component
@Slf4j
public class MiscDataTask implements ScheduledOfTask {

    @Autowired
    private TaskExecutor taskExecutor;

    @Autowired
    private GdszczLpBillVoucherRelService lpBillVoucherRelService;

    @Autowired
    private SpringScheduledCronService cronService;

    @Autowired
    private SysConfigService configService;

    @Autowired
    private GDSZCZUtils gdszczUtils;

    Integer cronId = null;

    @Override
    public void setCronId(Integer cronId) {
        this.cronId = cronId;
    }

    @Override
    public void execute() {
        try {
            log.info("start excute MiscDataTask");

            String updateStartTime = "";
            SpringScheduledCron cron = cronService.findById(cronId);
            if (cron != null && cron.getLastExcuteTime() != null) {
                updateStartTime = DateUtil.format(cron.getLastExcuteTime());
            }

            //异步将离线文件写入数据库
            String finalUpdateStartTime = updateStartTime;
            CompletableFuture.runAsync(() -> {
                trigger(finalUpdateStartTime);
            }, taskExecutor);

        } catch (Throwable e) {
            log.error("execute process has error(Throwable) : ", e);
        }
    }

    @Override
    public void trigger(String startTime) {
        String updateStartTime = String.valueOf(DateUtil.parseDate(startTime).getTime() / 1000);
        // 记录开始时间
        long start = System.currentTimeMillis();
        Date now = new Date();
        int currentYear = DateUtil.getYear();
        int fiscalYear = Integer.parseInt(configService.findByKey("gdszcz_fiscalYear").getCnfValue());
        if (StringUtil.isNotEmpty(startTime)) {
            fiscalYear = DateUtil.getYear(DateUtil.parseDate(startTime.substring(0, 10)));
        }

        try {
            Header[] headers = gdszczUtils.packetHeaders();

            String agencyCodeStr = configService.findByKey("gdszcz_agencyCode").getCnfValue();
            String[] agencyCodeArray = agencyCodeStr.split(",");
            for (String agencyCode : agencyCodeArray) {
                Optional<SysCompany> first = Globals.companyList.stream().filter(company -> company.getAgencyCode().equals(agencyCode)).findFirst();

                int startYear = fiscalYear;
                while (startYear <= currentYear) {
                    if (startYear <= 2021) {//不同步2021年前的数据
                        startYear++;
                        continue;
                    }

                    //1. 凭证辅助
                    syncLpBillVoucherRel(agencyCode, startYear, updateStartTime, first, headers);

                    startYear++;
                }
            }

            //更新最后执行成功时间
            cronService.updateExcuteTime(cronId, now, 1, null, (System.currentTimeMillis() - start) / 60000);
        } catch (Exception e) {
            log.error(e.getMessage());
            //更新最后执行失败时间
            cronService.updateExcuteTime(cronId, now, 0, e.getMessage(), (System.currentTimeMillis() - start) / 60000);
        }
    }


    /**
     * lp_bill_voucher_rel 凭证关联
     */
    private void syncLpBillVoucherRel(String agencyCode, Integer fiscalYear, String updateStartTime, Optional<SysCompany> first, Header[] headers) throws IOException {
        CommonRequest request = gdszczUtils.packetRequest(agencyCode, fiscalYear, updateStartTime, "lp_bill_voucher_rel");
        String responseLpBillVouRel = HttpUtils.requestForJson(MessageFormat.format(GDSZCZConstant.lp_bill_vou_rel_query_url, configService.findByKey("gdszcz_apiurl").getCnfValue()), JSONObject.toJSONString(request), headers);
        CommonResponse<List<GdszczLpBillVoucherRel>> responseLpBillVouRelData = JSONObject.parseObject(responseLpBillVouRel, new TypeReference<CommonResponse<List<GdszczLpBillVoucherRel>>>() {
        });
        log.info(String.format("lp_bill_vou_rel_query_url--请求:agencyCode:{},fiscalYear:{},updateStartTime:{};响应:resultCode：{},resultMessage:{},resultCount:{}"), request.getAgencyCode(), request.getFiscalYear(), request.getUpdateStartTime(), responseLpBillVouRelData.getResultCode(), responseLpBillVouRelData.getResultMessage(), responseLpBillVouRelData.getData().size());
        if (responseLpBillVouRelData.getResultCode().equals("000")) {
            for (GdszczLpBillVoucherRel s : responseLpBillVouRelData.getData()) {
                int existCount = lpBillVoucherRelService.exists(s.getRelGuid());
                if (existCount == 0) {
                    if (first.isPresent()) {
                        s.setAgencyCode(first.get().getId());
                    }
                    lpBillVoucherRelService.save(s);
                }
            }
        }
    }
}

